home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Plurals
/
mp_xnet.m
< prev
next >
Wrap
Text File
|
1992-07-15
|
10KB
|
349 lines
/*
* Paralation Lisp
*
* Author: S.C.Merrall
*
* File: mp_xnet.m
*
* Contents: mp_xnet
* get
* edge
*
* Description: The functions in this file were created
* explicitly to make handling wrapped nearest
* neighbour communication easier. The most
* important difference is that teh functions do
* not work on single offsets but a list of
* offsets which is transferred between the
* scratch spaces of the host and ACU
*
* Change History:
*
* Date Name Comment
* -------- ---- -------
* 05:06:92 SCM Created
* 17:06:92 SCM Added edge, which is a context stack modifier
*/
#include <mpl.h>
#include <stdio.h>
#include "proc_pair.h"
#include "mp_eubang.h" /* Includes constant.h too */
#include "mp_object.h"
#include "mp_debug_off.h"
#include "mp_mem_mgmt.h"
#include "mp_gc.h"
#include "mp_utils.h"
/*----------------------------------------------------------------------------*
* Function : get
*
* Parameters : MPC: The context of the plural
* MP_PluralHeap MPPH_data: The plural to be shifted in
* the given direction
* int direction: The direction to shift in
*
* Description: Encodes the lisp objects into the scratch space shifts them
* in the specified direction builds copies in the pes and
* the value of the argument is now the shifted structures
*
* Result : int FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int get( object MPC, MP_PluralHeap MPPH_data, int direction )
#else
int get( MPC, MPPH_data, direction )
object MPC;
MP_PluralHeap MPPH_data;
int direction;
#endif
{
int delta_x = 0;
int delta_y = 0;
plural int other_edge;
MP_PluralHeap MPPH_pluralHeap;
plural int index;
DBG_CALL("get");
DBG_ARGS(fprintf(dbg,"MPC=%x,",MPC);DBG_PARG("MPPH_data","%x ",MPPH_data);fprintf(dbg,"direction=%d",direction));
OM_with_context(MPC) {
scratch[0] = 1;
encode(MPPH_data);
switch (direction) {
case MP_NORTH: delta_y = -1; break;
case MP_SOUTH: delta_y = 1; break;
case MP_WEST : delta_x = 2; break;
case MP_EAST : delta_x = -2; break;
}
DEBUG(fprintf(dbg,"delta_x=%d,delta_y=%d",delta_x,delta_y));
pp_xsend(delta_y,delta_x, (plural char *plural) scratch,
(plural char *plural) scratch, SCRATCH_MEMORY_SIZE);
if ((((direction == MP_NORTH) || (direction == MP_SOUTH)) &&
(OA_height(MPC) == PP_nyproc)) ||
(((direction == MP_WEST) || (direction == MP_EAST)) &&
(OA_width(MPC) == PP_nxproc))) {
}
else if (((direction==MP_NORTH) && OM_top_edge(MPC)) ||
((direction==MP_SOUTH) && OM_bottom_edge(MPC)) ||
((direction==MP_WEST) && OM_left_edge(MPC)) ||
((direction==MP_EAST) && OM_right_edge(MPC))) {
DEBUG(DBG_PARG("iproc"," %d",iproc));
other_edge = ((iyproc - (delta_y * OA_height(MPC))) * nxproc) +
((ixproc + (OA_width(MPC) * delta_x)) % nxproc);
other_edge = (other_edge + nproc ) % nproc;
DEBUG(DBG_PARG("other_edge"," %d",other_edge));
ss_rfetch(other_edge,scratch,scratch,SCRATCH_MEMORY_SIZE);
}
index = 1;
if (decode(MPPH_data, &index)== FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: decode stage of get failed"));
mp_error = MP_DECODE_IN_GET_FAILED;
return FAIL;
}
} /* matches POM_with_conttext(MPC) */
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : mp_xnet
*
* Parameters : int direction: Indicating north, south, east or west
* int no_of_ofsts:Number of offsets
* int *fe_address:Where the offset list is on the host
*
* Description: The list of offsets form a strip in the appropriate dimension
* of a tiled virtual processor set, we want to shift them in
* desired direction carrying the overflow between the tiles
* with toroidal wrap around.
*
* Result : int: FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
visible int mp_xnet(int direction,int no_of_offsets,char *fe_address )
#else
visible int mp_xnet( direction, no_of_offsets, fe_address )
int direction;
int no_of_offsets;
char *fe_address;
#endif
{
natural first_ofst = 0;
int i, delta_x, delta_y;
natural *natural_scratch = (natural *) acu_scratch;
plural natural tmp, gws;
MP_PluralHeap MPPH_tmp;
int from_iproc, to_iproc;
object MPC;
plural int index;
DBG_CALL("mp_xnet");
DBG_ARGS(fprintf(dbg,"direction=%d, no_of_ofsts=%d, fe_address=%x",direction,no_of_offsets,fe_address));
if (copyIn(fe_address, acu_scratch, SCRATCH_MEMORY_SIZE) != 0) {
mp_error = MP_COPY_IN_FAILED;
DBG_FAIL(fprintf(dbg,"FAIL: Error paging in offset list"));
return FAIL;
}
PP_on_set() {
/* do all the shifts */
for (i=0; i< no_of_offsets; i++) {
MPC = (object) natural_scratch[(i*2)];
MPP_2_MPPH( MPPH_tmp, natural_scratch[(i*2)+1]);
if (get(MPC, MPPH_tmp, direction) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: get failed for %dth plural", i));
return FAIL;
}
}
/* now handle edge condition thingies, we expect most of the contexts
* to be the same so we set the activity to the edge of it to start off
*/
MPPH_tmp = &gws;
MPC = (object) natural_scratch[0];
OM_with_context(MPC) {
if (((direction==MP_NORTH) && OM_top_edge(MPC)) ||
((direction==MP_SOUTH) && OM_bottom_edge(MPC)) ||
((direction==MP_WEST) && OM_left_edge(MPC)) ||
((direction==MP_EAST) && OM_right_edge(MPC))) {
gws = plural_memory[natural_scratch[0+1]];
for (i=1; i<no_of_offsets; i++) {
if (MPC == (object) natural_scratch[2*i]) {
tmp = plural_memory[natural_scratch[(2*i)+1]];
plural_memory[natural_scratch[(2*i)+1]] = gws;
gws = tmp;
MPC = (object) natural_scratch[2*i];
}
else { /* This is the last context */
from_iproc = selectFirst();
scratch[0] = 1;
DEBUG(DBG_PARG("iproc","%d ",iproc));
DEBUG(DBG_PARG("scratch[0-3]","%08x ",*((plural int *) scratch)));
DEBUG(DBG_PARG("type","%d ",OA_info(MPPH_tmp)));
encode(MPPH_tmp);
DEBUG(DBG_PARG("scratch[0-3]","%08x ",*((plural int *) scratch)));
DEBUG(DBG_PARG("scratch[4-7]","%08x ",*(((plural int *) scratch)+1)));
all {
PP_on_set() {
MPC = (object) natural_scratch[2*i];
OM_with_context(MPC) {
if (((direction==MP_NORTH) && OM_top_edge(MPC)) ||
((direction==MP_SOUTH) && OM_bottom_edge(MPC)) ||
((direction==MP_WEST) && OM_left_edge(MPC)) ||
((direction==MP_EAST) && OM_right_edge(MPC))) {
DEBUG(DBG_PARG("iproc","%d ",iproc));
to_iproc = selectFirst();
DEBUG(fprintf(dbg,"from_iproc=%d, to_iproc=%d",from_iproc,to_iproc));
delta_y = -((from_iproc/nxproc)-(to_iproc/nxproc));
delta_x = (from_iproc-to_iproc)%nxproc;
DEBUG(fprintf(dbg,"delta_x=%d, delta_y=%d",delta_x, delta_y));
ss_xfetch(delta_y,delta_x,scratch,scratch,
SCRATCH_MEMORY_SIZE);
DEBUG(DBG_PARG("scratch[0-3]","%08x ",*((plural int *) scratch)));
DEBUG(DBG_PARG("scratch[4-7]","%08x ",*(((plural int *) scratch)+1)));
index = 1;
DEBUG(DBG_PARG("gws","%d ",gws));
decode(MPPH_tmp,&index);
DEBUG(DBG_PARG("gws","%d ",gws));
DEBUG(DBG_PARG("type","%d ",OA_info(MPPH_tmp)));
DEBUG(DBG_PARG("value","%d ",*(plural int *plural)OA_data(MPPH_tmp)));
tmp = plural_memory[natural_scratch[(2*i)+1]];
DEBUG(DBG_PARG("tmp","%d ",tmp));
plural_memory[natural_scratch[(2*i)+1]] = gws;
gws = tmp;
scratch[0] = 1;
encode(MPPH_tmp);
ss_xsend(delta_y,delta_x,scratch,scratch,
SCRATCH_MEMORY_SIZE);
}
}
}
}
DEBUG(DBG_PARG("iproc","%d ",iproc));
index = 1;
decode(MPPH_tmp,&index);
}
}
plural_memory[natural_scratch[0+1]] = gws;
}
}
}
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : edge
*
* Parameters : object MPC: The MasPar context whose contexts stacks we
* are going to munge.
* int direction: The edge we want active
*
* Description: Context stack modifier in the same way as the foc functions
* (perhaps it should be in that module) so that the indicated
* edge of the rectangular context is active
*
* Result : int:
*---------------------------------------------------------------------------*/
#ifdef __STDC__
visible int mp_edge( object MPC, int direction )
#else
visible int mp_edge( MPC, direction )
object MPC;
int direction;
#endif
{
int result;
plural natural old_context;
plural natural *plural new_context;
MP_PluralHeap MPPH_context_stack;
DBG_CALL("mp_edge");
DBG_ARGS(fprintf(dbg,"MPC=%x, direction=%d",MPC,direction));
OM_with_context(MPC) {
MPP_2_MPPH(MPPH_context_stack, OA_offset(MPC));
old_context = * (plural natural *plural) OA_data(MPPH_context_stack);
if (cons(MPPH_context_stack, MPPH_context_stack,
MPPH_context_stack)==FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to cons up context stack"));
return FAIL;
}
new_context = (plural natural *plural) OA_data(MPPH_context_stack);
*new_context = NIL;
if (old_context != NIL) {
if (((direction == MP_NORTH) && OM_top_edge(MPC)) ||
((direction == MP_SOUTH) && OM_bottom_edge(MPC)) ||
((direction == MP_EAST) && OM_right_edge(MPC)) ||
((direction == MP_WEST) && OM_left_edge(MPC))) {
*new_context = NOT_NIL;
}
}
if(globalor(*new_context != NIL) == 0) result = MP_NONE_ACTIVE;
else result = MP_SOME_ACTIVE;
}
DBG_EXIT(fprintf(dbg,"SUCCESS: %d",result));
return result;
}